/*
 * 文件名：FileHelper.java
 * 版权：(C)版权所有2013-2013 com.zilla
 * 描述：文件处理工具类
 * 修改人：ze.chen
 * 修改时间：2013-6-4 上午9:36:46
 */
package com.zilla.android.zillacore.libzilla.file;

import android.annotation.SuppressLint;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import com.github.snowdream.android.util.Log;
import com.zilla.android.zillacore.libzilla.Zilla;
import com.zilla.android.zillacore.libzilla.util.Util;

import java.io.*;
import java.text.DecimalFormat;
import java.util.ArrayList;

/**
 * 文件处理工具类<br>
 * 文件处理工具类,提供文件创建,删除,判断是否存在,拷贝,保存,读取;及sd卡状态等方法
 *
 * @author ze.chen
 * @version 1.0
 * @date 2013-6-4 下午1:54:54
 */
public class FileHelper {

    /**
     * 缓存路径，没有设为常量，在应用初始化的时候，根据具体应用做相应的目录变更
     */
    public static String PATH_CACHE = Environment.getExternalStorageDirectory().getAbsolutePath() + "/%s/cache/";

    /**
     * 下载路径，没有设为常量，在应用初始化的时候，根据具体应用做相应的目录变更
     */
    public static String PATH_DOWNLOAD = Environment.getExternalStorageDirectory().getAbsolutePath() + "/%s/DOWNLOAD/";

    /**
     * 应用文件存储位置
     */
    public static final String PATH_FILES = Zilla.APP.getDir("files", 0).getAbsolutePath() + "/";

    /**
     * 应用图标存储位置
     */
    public static final String PATH_DRAWABLE = Zilla.APP.getDir("drawables", 0).getAbsolutePath() + "/";

    /**
     * 闪屏图片存储路径
     */
    public static final String PATH_LAUNCH = Zilla.APP.getDir("launch", 0).getAbsolutePath() + "/";

    /**
     * 如果需要Cookie记录用户信息，存储在这里
     */
    public static final String PATH_COOKIE = Zilla.APP.getDir("cookie", 0).getAbsolutePath() + "/";

    /**
     * 截图位置
     */
    public static final String PATH_CAPTURE = Zilla.APP.getDir("capture", 0).getAbsolutePath() + "/";

    /**
     * 路径初始化
     *
     * @param path
     */
    public static void initPath(String path) {
        PATH_CACHE = String.format(PATH_CACHE, path);
        PATH_DOWNLOAD = String.format(PATH_DOWNLOAD, path);
    }

    /**
     * 由指定的路径和文件名创建文件
     *
     * @param path
     * @param name
     * @return
     * @throws java.io.IOException
     */
    public static File createFile(String path, String name) throws IOException {
        File folder = new File(path);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        File file = new File(path + name);
        if (!file.exists()) {
            file.createNewFile();
        }
        return file;
    }

    /**
     * 根据指定的路径创建文件
     *
     * @param filepath
     * @return
     * @throws java.io.IOException
     */
    public static File createFile(String filepath) throws IOException {
        int last_seperate = filepath.lastIndexOf("/") + 1;
        String path = filepath.substring(0, last_seperate);
        String name = filepath.substring(last_seperate);
        return createFile(path, name);
    }

    /**
     * 删除指定文件
     *
     * @param path
     * @param name
     */
    public static void deleteFile(String path, String name) {
        if (!fileExist(path, name)) {
            return;
        }
        File file = new File(path + name);
        file.delete();
    }

    /**
     * 判断文件是否存在
     *
     * @param path
     * @param name
     * @return
     */
    public static boolean fileExist(String path, String name) {
        File file = new File(path + name);
        if (file.exists() & !file.isDirectory()) {
            return true;
        }
        return false;
    }

    /**
     * 拷贝文件
     *
     * @param srcPath
     * @param srcName
     * @param desPath
     * @param desName
     * @return boolean
     */
    public static boolean copyFile(String srcPath, String srcName, String desPath, String desName) {
        if (!fileExist(srcPath, srcName)) {
            return false;
        }

        FileInputStream fis = null;
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        try {
            File inFile = new File(srcPath, srcName);
            File outFile = new File(desPath, desName);

            if (!fileExist(desPath, desName)) {
                createFile(desPath, desName);
            }

            fis = new FileInputStream(inFile);
            bis = new BufferedInputStream(fis);

            fos = new FileOutputStream(outFile);
            bos = new BufferedOutputStream(fos);

            byte[] buffer = new byte[1024 * 8];
            int len = -1;
            while ((len = fis.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            bos.flush();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            Util.closeStream(bis);
            Util.closeStream(fis);
            Util.closeStream(bos);
            Util.closeStream(fos);
        }
        return false;
    }

    /**
     * 保存bitmap成图片
     *
     * @param bitmap
     * @param name
     * @param path
     * @throws java.io.IOException
     */
    public static void saveBitmap(Bitmap bitmap, String name, String path) throws IOException {
        if (bitmap == null) {
            return;
        }
        File file = createFile(path, name);
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 75, fos);
        } finally {
            Util.closeStream(fos);
        }
    }

    /**
     * 保存bitmap成图片
     *
     * @param bitmap
     * @param name   完整的文件名（带有路径）
     * @throws java.io.IOException
     */
    public static void saveBitmap(Bitmap bitmap, String name) throws IOException {
        if (bitmap == null) {
            return;
        }
        File f = new File(name);
        if (!f.exists()) {
            f.createNewFile();
        }
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(name);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 75, fos);
        } finally {
            Util.closeStream(fos);
        }
    }

    /**
     * 写入文件
     *
     * @param dataPath
     * @param data
     * @throws java.io.IOException
     */
    public static synchronized void saveData(String dataPath, String data) throws IOException {
        File file = createFile(dataPath);
        RandomAccessFile raf = new RandomAccessFile(file, "rws");
        // raf.seek(0);
        byte[] byteds = data.getBytes();
        raf.setLength(byteds.length);
        raf.write(byteds);
        Util.closeStream(raf);
    }

    /**
     * 读取文件内容，并以字符串形式返回（该方法去掉了注释：//和#）path或者file只要能获取绝对路径即可
     *
     * @param path
     * @param file
     * @throws java.io.IOException
     */
    public static String readFile(String path, String file) throws IOException {
        if (path == null)
            path = "";
        if (file == null)
            file = "";
        FileInputStream fis = new FileInputStream(path + file);
        return readFromInputStream(fis);

    }

    /**
     * 将输入流内容写入字符串
     *
     * @param is
     * @return
     * @throws java.io.IOException
     */
    private static String readFromInputStream(InputStream is) throws IOException {
        InputStreamReader inputReader = null;
        BufferedReader bufReader = null;
        StringBuilder sb = new StringBuilder();
        try {
            inputReader = new InputStreamReader(is);
            bufReader = new BufferedReader(inputReader);
            String line = "";
            while ((line = bufReader.readLine()) != null) {
                if (line.startsWith("//") || line.startsWith("#")) {
                    continue;
                }
                sb.append(line);
            }
        } finally {
            Util.closeStream(bufReader);
            Util.closeStream(inputReader);
            Util.closeStream(is);
        }
        return sb.toString();
    }

    /**
     * SD卡是否可用（挂载）
     *
     * @return
     */
    public static boolean isSDCardMounted() {
        /*
         * Environment.MEDIA_MOUNTED // sd卡在手机上正常使用状态
		 * Environment.MEDIA_UNMOUNTED // 用户手工到手机设置中卸载sd卡之后的状态
		 * Environment.MEDIA_REMOVED // 用户手动卸载，然后将sd卡从手机取出之后的状态
		 * Environment.MEDIA_BAD_REMOVAL // 用户未到手机设置中手动卸载sd卡，直接拨出之后的状态
		 * Environment.MEDIA_SHARED // 手机直接连接到电脑作为u盘使用之后的状态
		 * Environment.MEDIA_CHECKINGS // 手机正在扫描sd卡过程中的状态
		 */
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            return true;
        }
        return false;
    }

    @SuppressLint("NewApi")
    public static long calculateFilePathSize(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            file.mkdirs();
            return 0l;
        }
        return file.getTotalSpace();
    }

    /**
     * 删除路径
     *
     * @param filePath
     */
    public static void clearFilePath(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            return;
        }
        if (file.isFile()) {
            file.delete();
            return;
        }
        if (file.isDirectory()) {
            String[] children = file.list();
            if (children == null) {// 该目录没有子元素(空目录)
                file.delete();
                return;
            }
            for (String child : children) {
                clearFilePath(child);
            }
        }
    }

    /**
     * 获取数据库升级脚本
     *
     * @return
     */
    public static ArrayList<String> getUpgradeSqls() {
        ArrayList<String> result = new ArrayList<String>();
        InputStream is = null;
        InputStreamReader reader = null;
        BufferedReader br = null;
        try {
            is = Zilla.APP.getAssets().open("/config/upgrade.sql");
            reader = new InputStreamReader(is);
            br = new BufferedReader(reader);
            String line = null;
            while ((line = br.readLine()) != null) {
                if (!line.startsWith("--")) {
                    result.add(line);
                }
            }
        } catch (FileNotFoundException e) {
            Log.e(e.getMessage());
        } catch (IOException e) {
            Log.e(e.getMessage());
        } finally {
            Util.closeStream(br);
            Util.closeStream(reader);
            Util.closeStream(is);
        }
        return result;
    }

    /**
     * 序列化对象
     *
     * @param obj
     * @return
     */
    public static boolean saveObj(Object obj, String path) {
        ObjectOutputStream objOutput = null;
        try {
            objOutput = new ObjectOutputStream(new FileOutputStream(path));
            objOutput.writeObject(obj);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally {
            Util.closeStream(objOutput);
        }
        return true;
    }

    /**
     * 反序列化对象
     *
     * @param path
     * @return
     */
    public static Object readObj(String path) {
        Object result = null;
        ObjectInputStream objInput = null;
        try {
            objInput = new ObjectInputStream(new FileInputStream(path));
            result = objInput.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            Util.closeStream(objInput);
        }
        return result;
    }

    /**
     * 文件大小格式化B,K,M,G
     *
     * @param fileS 文件长度
     * @return
     */
    public static String formetFileSize(long fileS) {// 转换文件大小
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString = "";
        if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + "B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + "K";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + "M";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + "G";
        }
        return fileSizeString;
    }

    /**
     * @param context   上下文对象
     * @param fileUrl   文件的URI
     * @param mediaDATA MediaStore.Images.Media.DATA||MediaStore.Audio.Media.DATA||MediaStore.Video.Media.DATA
     * @return
     */
    public static String getRealPath(Context context, Uri fileUrl, String mediaDATA) {
        String fileName = null;
        Uri filePathUri = fileUrl;
        if (fileUrl != null) {
            if (fileUrl.getScheme().toString().compareTo("content") == 0)           //content://开头的uri
            {
                Cursor cursor = context.getContentResolver().query(fileUrl, null, null, null, null);
                if (cursor != null && cursor.moveToFirst()) {
                    int column_index = cursor.getColumnIndexOrThrow(mediaDATA);
                    fileName = cursor.getString(column_index);          //取出文件路径
                    if (!fileName.startsWith("/mnt")) { //检查是否有”/mnt“前缀
                        fileName = "/mnt" + fileName;
                    }
                    cursor.close();
                }
            } else if (fileUrl.getScheme().compareTo("file") == 0)         //file:///开头的uri
            {
                fileName = filePathUri.toString().replace("file://", ""); //替换file://
                if (!fileName.startsWith("/mnt")) { //加上"/mnt"头
                    fileName += "/mnt";
                }
            }
        }
        return fileName;
    }
}
